#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
班次参数处理器

负责处理三班制排班接口的参数，包括班次模式、时间间隔等。

作者: AI助手
日期: 2025-04-28
"""

import logging
import re
from datetime import datetime, timedelta

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class ShiftParamsProcessor:
    """班次参数处理器类"""

    def __init__(self, config_params=None):
        """
        初始化班次参数处理器

        Args:
            config_params: 全局配置参数
        """
        self.config_params = config_params
        logger.info("参数处理器初始化完成")

    def process_params(self, params):
        """
        处理排班参数

        Args:
            params: 排班参数字典

        Returns:
            处理后的参数字典
        """
        # 检查是否有特殊参数
        if self._has_special_params(params):
            return self._process_special_params(params)
        else:
            logger.info("未检测到特殊参数，使用原始参数")
            return params

    def _has_special_params(self, params):
        """
        检查是否有特殊参数

        Args:
            params: 排班参数字典

        Returns:
            是否有特殊参数
        """
        special_params = ['shift_mode', 'custom_shifts', 'time_interval_minutes']
        return any(param in params for param in special_params)

    def _process_special_params(self, params):
        """
        处理特殊参数

        Args:
            params: 排班参数字典

        Returns:
            处理后的参数字典
        """
        processed_params = params.copy()

        # 处理班制模式
        if 'shift_mode' in params:
            shift_mode = params['shift_mode']
            if isinstance(shift_mode, (int, str)) and str(shift_mode) in ['1', '2', '3']:
                processed_params['shift_mode'] = int(shift_mode)
                processed_params['day_segments'] = int(shift_mode)
            else:
                logger.warning(f"无效的班制模式参数: {shift_mode}，使用默认值: 3")
                processed_params['shift_mode'] = 3
                processed_params['day_segments'] = 3

        # 处理时间间隔
        if 'time_interval_minutes' in params:
            time_interval = params['time_interval_minutes']
            try:
                time_interval = int(time_interval)
                if 10 <= time_interval <= 60:
                    processed_params['time_interval_minutes'] = time_interval
                else:
                    logger.warning(f"时间间隔参数超出范围: {time_interval}，使用默认值: 20")
                    processed_params['time_interval_minutes'] = 20
            except (ValueError, TypeError):
                logger.warning(f"无效的时间间隔参数: {time_interval}，使用默认值: 20")
                processed_params['time_interval_minutes'] = 20

        # 处理自定义班次时间
        if 'custom_shifts' in params and params['custom_shifts']:
            custom_shifts = params['custom_shifts']
            if isinstance(custom_shifts, list) and len(custom_shifts) > 0:
                validated_shifts = self._validate_custom_shifts(custom_shifts)
                if validated_shifts:
                    processed_params['custom_shifts'] = validated_shifts
                else:
                    logger.warning("无效的自定义班次时间，使用默认班次时间")
                    processed_params['custom_shifts'] = None
            else:
                logger.warning("无效的自定义班次时间格式，使用默认班次时间")
                processed_params['custom_shifts'] = None

        return processed_params

    def _validate_custom_shifts(self, custom_shifts):
        """
        验证自定义班次时间

        Args:
            custom_shifts: 自定义班次时间列表

        Returns:
            验证后的自定义班次时间列表，如果无效则返回None
        """
        validated_shifts = []
        time_pattern = re.compile(r'^([01]\d|2[0-3]):([0-5]\d)$')

        for shift in custom_shifts:
            if not isinstance(shift, dict):
                logger.warning(f"无效的班次格式: {shift}")
                continue

            if 'name' not in shift or 'start_time' not in shift or 'end_time' not in shift:
                logger.warning(f"班次缺少必要字段: {shift}")
                continue

            name = shift['name']
            start_time = shift['start_time']
            end_time = shift['end_time']

            # 验证时间格式
            if not time_pattern.match(start_time) or not time_pattern.match(end_time):
                logger.warning(f"无效的时间格式: {start_time}-{end_time}")
                continue

            # 验证班次名称 - 放宽验证条件
            # 1. 接受数字字符串 '1', '2', '3'
            # 2. 接受标准班次名称 'morning_shift', 'afternoon_shift', 'night_shift'
            # 3. 接受中文班次名称 '早班', '中班', '夜班'
            valid_names = ['1', '2', '3', 'morning_shift', 'afternoon_shift', 'night_shift', '早班', '中班', '夜班']

            if not isinstance(name, str) or not name.strip():
                logger.warning(f"无效的班次名称: {name}")
                continue

            # 如果名称不在有效名称列表中，但是是数字字符串，则映射到对应的数字
            if name not in valid_names and name.isdigit():
                if name in ['1', '2', '3']:
                    # 数字1-3是有效的
                    pass
                else:
                    logger.warning(f"无效的数字班次名称: {name}，应为'1', '2', '3'之一")
                    continue

            # 如果名称不在有效名称列表中，且不是数字，则尝试进行映射
            if name not in valid_names and not name.isdigit():
                # 尝试映射到标准名称
                name_mapping = {
                    '班次1': '1', '班次2': '2', '班次3': '3',
                    'shift1': '1', 'shift2': '2', 'shift3': '3',
                    'shift_1': '1', 'shift_2': '2', 'shift_3': '3',
                    '1班': '1', '2班': '2', '3班': '3'
                }

                if name in name_mapping:
                    name = name_mapping[name]
                    logger.info(f"班次名称映射: {shift['name']} -> {name}")
                else:
                    logger.warning(f"无法映射的班次名称: {name}")
                    continue

            validated_shifts.append({
                'name': name,
                'start_time': start_time,
                'end_time': end_time
            })

        # 确保班次按名称排序
        validated_shifts.sort(key=lambda x: x['name'])

        # 如果没有有效的班次，返回None
        if not validated_shifts:
            return None

        return validated_shifts

    def calculate_time_slots(self, time_interval_minutes):
        """
        计算一天的时间段数量

        Args:
            time_interval_minutes: 时间间隔（分钟）

        Returns:
            时间段数量
        """
        if not time_interval_minutes or time_interval_minutes <= 0:
            logger.warning(f"无效的时间间隔: {time_interval_minutes}，使用默认值: 20")
            time_interval_minutes = 20

        # 计算一天的时间段数量
        minutes_per_day = 24 * 60
        time_slots = minutes_per_day // time_interval_minutes

        return time_slots

    def generate_time_slots(self, time_interval_minutes):
        """
        生成一天的时间段列表

        Args:
            time_interval_minutes: 时间间隔（分钟）

        Returns:
            时间段列表，格式为 ["00:00-00:20", "00:20-00:40", ...]
        """
        if not time_interval_minutes or time_interval_minutes <= 0:
            logger.warning(f"无效的时间间隔: {time_interval_minutes}，使用默认值: 20")
            time_interval_minutes = 20

        time_slots = []
        current_time = datetime.strptime("00:00", "%H:%M")
        end_of_day = datetime.strptime("23:59", "%H:%M")

        while current_time < end_of_day:
            next_time = current_time + timedelta(minutes=time_interval_minutes)
            if next_time > end_of_day:
                next_time = end_of_day

            time_slot = f"{current_time.strftime('%H:%M')}-{next_time.strftime('%H:%M')}"
            time_slots.append(time_slot)

            current_time = next_time

        return time_slots

    def map_shift_mode_to_name(self, shift_mode):
        """
        将班制模式映射到名称

        Args:
            shift_mode: 班制模式（1, 2, 3）

        Returns:
            班制模式名称（one_shift, two_shift, three_shift）
        """
        shift_mode_map = {
            1: "one_shift",
            2: "two_shift",
            3: "three_shift"
        }

        if shift_mode in shift_mode_map:
            return shift_mode_map[shift_mode]
        else:
            logger.warning(f"无效的班制模式: {shift_mode}，使用默认值: three_shift")
            return "three_shift"

    def get_enabled_shifts(self, shift_mode):
        """
        获取启用的班次列表

        Args:
            shift_mode: 班制模式名称（one_shift, two_shift, three_shift）

        Returns:
            启用的班次列表
        """
        shift_mode_map = {
            "one_shift": ["morning_shift"],
            "two_shift": ["morning_shift", "afternoon_shift"],
            "three_shift": ["morning_shift", "afternoon_shift", "night_shift"]
        }

        if shift_mode in shift_mode_map:
            return shift_mode_map[shift_mode]
        else:
            logger.warning(f"无效的班制模式: {shift_mode}，使用默认值: three_shift")
            return shift_mode_map["three_shift"]

    def get_shift_mode_name(self, shift_mode):
        """
        获取班制模式的中文名称

        Args:
            shift_mode: 班制模式名称（one_shift, two_shift, three_shift）

        Returns:
            班制模式的中文名称
        """
        shift_mode_name_map = {
            "one_shift": "一班制",
            "two_shift": "二班制",
            "three_shift": "三班制"
        }

        if shift_mode in shift_mode_name_map:
            return shift_mode_name_map[shift_mode]
        else:
            logger.warning(f"无效的班制模式: {shift_mode}，使用默认值: 三班制")
            return shift_mode_name_map["three_shift"]
